package fr.umlv.m2.uwp2011.web.client.professor;

import java.util.LinkedList;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TabBar;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;

import fr.umlv.m2.uwp2011.persistence.sujet.Cours;
import fr.umlv.m2.uwp2011.persistence.sujet.Exam;
import fr.umlv.m2.uwp2011.persistence.sujet.Projet;
import fr.umlv.m2.uwp2011.persistence.sujet.Sujet;
import fr.umlv.m2.uwp2011.persistence.sujet.TD;
import fr.umlv.m2.uwp2011.persistence.sujet.TP;
import fr.umlv.m2.uwp2011.service.matiere.DisplayMatiere;
import fr.umlv.m2.uwp2011.service.matiere.IMatiereService;
import fr.umlv.m2.uwp2011.service.matiere.IMatiereServiceAsync;
import fr.umlv.m2.uwp2011.service.sujet.DisplayCours;
import fr.umlv.m2.uwp2011.service.sujet.DisplayTD;
import fr.umlv.m2.uwp2011.service.sujet.DisplayTP;
import fr.umlv.m2.uwp2011.service.sujet.ICoursService;
import fr.umlv.m2.uwp2011.service.sujet.ICoursServiceAsync;
import fr.umlv.m2.uwp2011.service.sujet.ISujetService;
import fr.umlv.m2.uwp2011.service.sujet.ISujetServiceAsync;
import fr.umlv.m2.uwp2011.service.sujet.ITDService;
import fr.umlv.m2.uwp2011.service.sujet.ITDServiceAsync;
import fr.umlv.m2.uwp2011.service.sujet.ITPService;
import fr.umlv.m2.uwp2011.service.sujet.ITPServiceAsync;
import fr.umlv.m2.uwp2011.web.client.Application;
import fr.umlv.m2.uwp2011.web.client.Session;

public class ProfessorTeaching extends Composite {
	/**
	 * The professor list of subject. 
	 */
	private final ListBox subject;
	/**
	 * The category panel.
	 */
	private final HorizontalPanel categoriesPanel;

	/**
	 * The TabBar that contains cours, TP, TD ...
	 */
	private final TabBar bar;
	/**
	 * The add sujet Button.
	 */
	private final Button addSujetButton;

	/**
	 * dialog box of addSujetButton.
	 */
	private final DialogBox dialogBox;

	/**
	 * The header page panel.
	 */
	private final VerticalPanel headerPagePanel;

	/**
	 * The page panel.
	 */
	private VerticalPanel pagePanel;

	/**
	 * The main panel.
	 */
	private final VerticalPanel page;

	/**
	 * rpc service use for get matiere that user have.
	 */
	private final IMatiereServiceAsync matiereService;

	/**
	 * rpc service use for get cours of matiere.
	 */
	private final ICoursServiceAsync coursService;

	/**
	 * rpc service use for get td of matiere.
	 */
	private final ITDServiceAsync tdService;

	/**
	 * rpc service use for get tp of matiere.
	 */
	private final ITPServiceAsync tpService;

	/**
	 * rpc service use for remove a sujet.
	 */
	private final ISujetServiceAsync sujetService;

	/**
	 * list of matieres of the cursus.
	 */
	private final List<DisplayMatiere> listMatieres;

	/**
	 * current matiere that are display in div page.
	 */
	private DisplayMatiere currentMatiere;

	private Long cursus_id;

	/**
	 * session of the user.
	 */
	private final Session session;

	public ProfessorTeaching(final Session session) {		
		this.session = session;
		/****************************** Widgets Creation ******************************/
		this.matiereService = GWT.create(IMatiereService.class);
		this.coursService = GWT.create(ICoursService.class);
		this.tdService = GWT.create(ITDService.class);
		this.tpService = GWT.create(ITPService.class);
		this.sujetService = GWT.create(ISujetService.class);
		this.listMatieres = new LinkedList<DisplayMatiere>();

		this.subject = new ListBox();
		this.categoriesPanel = new HorizontalPanel();
		this.bar = new TabBar();

		this.addSujetButton = new Button();
		this.dialogBox = createDialogBox();

		this.headerPagePanel = new VerticalPanel();
		this.pagePanel = new VerticalPanel();
		this.page = new VerticalPanel();

		/*************************** Widgets initialization ***************************/
		this.cursus_id = 1L;
		if(session.getParameters().get("cursus") != null) {
			this.cursus_id = Long.valueOf(session.getParameters().get("cursus"));
		}

		this.bar.addTab("Cours");
		this.bar.addTab("TD");
		this.bar.addTab("TP");
		this.bar.addTab("Projet");
		this.bar.addTab("Examen");
		this.bar.selectTab(0);
		this.bar.addSelectionHandler(tabBarHandler());

		this.dialogBox.setGlassEnabled(true);
		this.dialogBox.setAnimationEnabled(true);
		this.addSujetButton.setText("Ajouter un cours");
		this.addSujetButton.addClickHandler(addSujet(dialogBox));


		/******************************** Widgets style *******************************/
		this.page.setWidth("770px");
		this.pagePanel.setWidth("746px");
		this.pagePanel.addStyleName("professorTeachingPagePanel");

		this.categoriesPanel.addStyleName("professorTeachingCategoriesPanel");
		this.addSujetButton.addStyleName("professorTeachingAddSujet");

		/******************************** Page building *******************************/   
		this.categoriesPanel.add(bar);
		this.headerPagePanel.add(this.subject);
		this.headerPagePanel.add(this.categoriesPanel);
		this.headerPagePanel.add(this.addSujetButton);

		this.page.add(pagePanel);
		this.initWidget(page);

		/******************************* Action handler *******************************/

		Long deleteSujet_id;
		if(session.getParameters().containsKey("delete_cours")) {
			deleteSujet_id = Long.parseLong(session.getParameters().get("delete_cours"));
			sujetService.deleteSujet(deleteSujet_id, deleteSujetCallback());
			//this.bar.selectTab(0);
		}
		else if(session.getParameters().containsKey("delete_td")) {
			deleteSujet_id = Long.parseLong(session.getParameters().get("delete_td"));
			sujetService.deleteSujet(deleteSujet_id, deleteSujetCallback());
			//this.bar.selectTab(1);
		}
		else if(session.getParameters().containsKey("delete_tp")) {
			deleteSujet_id = Long.parseLong(session.getParameters().get("delete_tp"));
			sujetService.deleteSujet(deleteSujet_id, deleteSujetCallback());
			//this.bar.selectTab(2);
		}


		matiereService.getByUserAndCursus(session.getUser().getLogin(), cursus_id, new AsyncCallback<List<DisplayMatiere>>() {

			@Override
			public void onSuccess(List<DisplayMatiere> listMatiere) {
				for(DisplayMatiere matiere : listMatiere) {
					listMatieres.add(matiere);
					subject.addItem(matiere.getLibelle(), matiere.getId().toString());
				}
				if(session.getParameters().containsKey("matiere_index")) {
					int index = Integer.parseInt(session.getParameters().get("matiere_index"));
					subject.setSelectedIndex(index);
					currentMatiere = listMatieres.get(subject.getSelectedIndex());
				}
				else {
					currentMatiere = listMatieres.get(0);
					subject.setSelectedIndex(0);
				}
				coursService.getByMatiereID(currentMatiere.getId(), displayCoursCallBack());        
			}
			@Override
			public void onFailure(Throwable arg0) {}
		});

		this.subject.addChangeHandler(new ChangeHandler() {
			@Override
			public void onChange(ChangeEvent arg0) {
				currentMatiere = listMatieres.get(subject.getSelectedIndex());
				bar.selectTab(0);
				coursService.getByMatiereID(currentMatiere.getId(), displayCoursCallBack());    
			}
		});
	}

	private ClickHandler addSujet(final DialogBox dialogBox) {
		return new ClickHandler() {
			public void onClick(ClickEvent sender) {
				dialogBox.center();
				dialogBox.show();
			}
		};
	}

	private DialogBox createDialogBox() {
		FormPanel formPanel = new FormPanel();
		FileUpload fileUpload = new FileUpload();
		fileUpload.setTitle("Ajouter un fichier");
		formPanel.setWidget(fileUpload);
		fileUpload.setSize("137px", "26px");

		final DialogBox dialogBox = new DialogBox();
		dialogBox.setText("Ajouter un sujet");

		// Create a table to layout the form options
		FlexTable layout = new FlexTable();
		layout.setCellSpacing(6);

		// Add some standard form options
		layout.setHTML(1, 0, "Titre");
		final TextBox titreTextBox = new TextBox();
		layout.setWidget(1, 1, titreTextBox);
		layout.setHTML(2, 0, "Description");
		final TextBox descTextBox = new TextBox();
		layout.setWidget(2, 1, descTextBox);

		Button closeButton = new Button( "Fermer", new ClickHandler() {
			public void onClick(ClickEvent event) {
				dialogBox.hide();
			}
		});

		Button addButton = new Button( "Ajouter", new ClickHandler() {
			public void onClick(ClickEvent event) {
				Sujet sujet;

				switch (bar.getSelectedTab()) {
				case 0:
					sujet = new Cours();
					sujet.setType(Sujet.COURS);
					break;
				case 1:
					sujet = new TD();
					sujet.setType(Sujet.TD);
					break;
				case 2:
					sujet = new TP();
					sujet.setType(Sujet.TP);
					break;
				case 3:
					sujet = new Projet();
					sujet.setType(Sujet.PROJET);
					break;
				case 4:
					sujet = new Exam();
					sujet.setType(Sujet.EXAM);
					break;
				default:
					sujet = new Cours();
					sujet.setType(Sujet.COURS);
					break;
				}
				sujet.setTitre(titreTextBox.getText());
				sujet.setDescription(descTextBox.getText());
				sujet.setMatiere(currentMatiere.getMatiere());
				sujetService.addSujet(sujet, new AsyncCallback<Boolean>() {

					@Override
					public void onFailure(Throwable caught) {}

					@Override
					public void onSuccess(Boolean result) {
						Window.alert("ajout reussi");
						Application.redirect("../Application.html?gwt.codesvr=127.0.0.1:9997#" +
								Application.PROFESSOR_TEACHING + "?login=" + session.getParameters().get("login") +
					              "&key=" + session.getParameters().get("key") +
					              "&cursus=" + cursus_id + 
					              "&matiere_index=" + subject.getSelectedIndex() +
					              "&reload");
					}
				});

				dialogBox.hide();
			}
		});


		layout.setWidget(3, 1, formPanel);
		layout.setWidget(4, 0, addButton);
		layout.setWidget(4, 1, closeButton);
		dialogBox.setWidget(layout);
		layout.getCellFormatter().setHorizontalAlignment(4, 0, HasHorizontalAlignment.ALIGN_RIGHT);
		layout.getCellFormatter().setHorizontalAlignment(4, 1, HasHorizontalAlignment.ALIGN_LEFT);
		return dialogBox;
	}

	/**
	 * Handler on select of tabBar
	 * @return SelectionHandler
	 */
	private SelectionHandler<Integer> tabBarHandler() {
		return new SelectionHandler<Integer>() {	
			@Override
			public void onSelection(SelectionEvent<Integer> event) {
				currentMatiere = listMatieres.get(subject.getSelectedIndex());
				switch (event.getSelectedItem()) {
				case 0:
					addSujetButton.setText("Ajouter un cours");
					addSujetButton.addClickHandler(addSujet(dialogBox));
					coursService.getByMatiereID(currentMatiere.getId(), displayCoursCallBack());
					break;
				case 1:
					addSujetButton.setText("Ajouter un TD");
					addSujetButton.addClickHandler(addSujet(dialogBox));
					tdService.getByMatiereID(currentMatiere.getId(), displayTDCallBack());
					break;
				case 2:
					addSujetButton.setText("Ajouter un TP");
					addSujetButton.addClickHandler(addSujet(dialogBox));
					tpService.getByMatiereID(currentMatiere.getId(), displayTPCallBack());
					break;
				default:
					addSujetButton.setText("Ajouter un cours");
					addSujetButton.addClickHandler(addSujet(dialogBox));
					coursService.getByMatiereID(currentMatiere.getId(), displayCoursCallBack());
					break;
				}
			}
		};
	}

	private AsyncCallback<Boolean> deleteSujetCallback() {
		return new AsyncCallback<Boolean>() {

			@Override
			public void onFailure(Throwable caught) {}

			@Override
			public void onSuccess(Boolean result) {
				if(result) {
					Window.alert("sujet supprimer");
				}

			}
		};
	}

	/**
	 * asyncCallback of coursService.getByMatiereID.
	 * @return AsyncCallback<List<DisplayCours>>
	 */
	private AsyncCallback<List<DisplayCours>> displayCoursCallBack() {
		return new AsyncCallback<List<DisplayCours>>() {

			@Override
			public void onFailure(Throwable arg0) {}

			@Override
			public void onSuccess(List<DisplayCours> listCours) {
				pagePanel.clear();
				pagePanel.add(headerPagePanel);
				for(int i=0; i<listCours.size(); i++) {
					ProfessorTeachingCourse professorTeachingCours = new ProfessorTeachingCourse(cursus_id, listCours.get(i), session, subject.getSelectedIndex());
					if(i%2 == 0) {
						professorTeachingCours.addStyleName("professorTeachingBackgroundBlue");
					}
					else {
						professorTeachingCours.addStyleName("professorTeachingBackgroundWhite");
					}
					pagePanel.add(professorTeachingCours);
				}
			}
		};	
	}

	/**
	 * asyncCallback of tdService.getByMatiereID.
	 * @return AsyncCallback<List<DisplayTD>>
	 */
	private AsyncCallback<List<DisplayTD>> displayTDCallBack() {
		return new AsyncCallback<List<DisplayTD>>() {

			@Override
			public void onFailure(Throwable arg0) {}

			@Override
			public void onSuccess(List<DisplayTD> listTD) {
				pagePanel.clear();
				pagePanel.add(headerPagePanel);
				for(int i=0; i<listTD.size(); i++) {
					ProfessorTeachingTD professorTeachingTD = new ProfessorTeachingTD(cursus_id, listTD.get(i), session, subject.getSelectedIndex());
					if(i%2 == 0) {
						professorTeachingTD.addStyleName("professorTeachingBackgroundBlue");
					}
					else {
						professorTeachingTD.addStyleName("professorTeachingBackgroundWhite");
					}
					pagePanel.add(professorTeachingTD);
				}
			}
		};	
	}

	/**
	 * asyncCallback of tpService.getByMatiereID.
	 * @return AsyncCallback<List<DisplayTP>>
	 */
	private AsyncCallback<List<DisplayTP>> displayTPCallBack() {
		return new AsyncCallback<List<DisplayTP>>() {

			@Override
			public void onFailure(Throwable arg0) {}

			@Override
			public void onSuccess(List<DisplayTP> listTP) {
				pagePanel.clear();
				pagePanel.add(headerPagePanel);
				for(int i=0; i<listTP.size(); i++) {
					ProfessorTeachingTP professorTeachingTP = new ProfessorTeachingTP(cursus_id, listTP.get(i), session, subject.getSelectedIndex());
					if(i%2 == 0) {
						professorTeachingTP.addStyleName("professorTeachingBackgroundBlue");
					}
					else {
						professorTeachingTP.addStyleName("professorTeachingBackgroundWhite");
					}
					pagePanel.add(professorTeachingTP);
				}
			}
		};	
	}


}
